import {
  Shader,
  ShaderData,
  ShaderProperty,
  ShaderPool,
  ShaderProgram,
  ShaderProgramPool,
  ShaderMacro,
  ShaderMacroCollection,
  ShaderDataGroup,
  ShaderLib
} from "@nirvana/shaders";

import { WebGLCanvas } from "@nirvana/canvas";
import { IndexBufferData, VertexBufferData, DataElement } from "@nirvana/core";
const textureUrl = require("./texture.png");
// console.log(textureUrl)
// 使用使用 Canvas
let canvas = document.getElementById("engine-nirvana");
// console.log(canvas);

const webCanvas = new WebGLCanvas(canvas, {
  // fullScreen: true, // 自动放大全屏
  // fixWidth: 500, // 放大
  // auto: true // 页面设置了canvas 样式
  // 2d: true,
});
// webCanvas.fullScreen();
const engine = webCanvas.engine;
const gl = engine.gl;
const pool1: ShaderProgramPool = new ShaderProgramPool();

const planeVS = `
attribute vec3 aVertexPosition;
attribute vec2 texCoord;
varying vec2 vtexCoord;
void main() {
  gl_Position = vec4(aVertexPosition, 1.0);
  vtexCoord = texCoord;
}
`;
const planeFS = `
varying vec2 vtexCoord;
uniform sampler2D u_Sampler;
void main() {
  gl_FragColor = texture2D(u_Sampler, vtexCoord);;
}
`;

const plane = Shader.create("plane", planeVS, planeFS);
console.log(plane, Shader.find("plane"));
const pool3: ShaderProgramPool = new ShaderProgramPool();
const shaderMacroCollection: ShaderMacroCollection = new ShaderMacroCollection();
console.log(shaderMacroCollection);
const planeProgram: ShaderProgram = plane.getShaderProgram(engine.gl, shaderMacroCollection, pool3);
console.log("plane", planeProgram);

const vBuffer = new VertexBufferData(
  new Float32Array([
    -0.5, 0.5, 0.0, 0.0, 0.0,//(x,y,z)(r,g,b)分别代表坐标和颜色
    -0.5,-0.5,0.0, 1.0,0.0,
    0.5,-0.5,0.0, 0.0,1.0,
    0.5,0.5,0.0, 1.0,1.0,
  ]),
  [
    new DataElement("aVertexPosition", 3, gl.FLOAT, false, 20, 0),
    new DataElement("texCoord", 2, gl.FLOAT, false, 20, 12)
  ]
);

function isPowerOf2(value) {
  return (value & (value - 1)) === 0;
}

function create1PixelTexture(gl, pixel) {
  const texture = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(pixel));
  return texture;
}

function createTexture(gl, url) {
  const texture = create1PixelTexture(gl, [128, 192, 255, 255]);
  // Asynchronously load an image
  const image = new Image();
  image.src = url;
  image.addEventListener("load", function () {
    // Now that the image has loaded make copy it to the texture.
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);

    // Check if the image is a power of 2 in both dimensions.
    if (isPowerOf2(image.width) && isPowerOf2(image.height)) {
      // Yes, it's a power of 2. Generate mips.
      gl.generateMipmap(gl.TEXTURE_2D);
    } else {
      // No, it's not a power of 2. Turn of mips and set wrapping to clamp to edge
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    }
    // gl.bindTexture(gl.TEXTURE_2D, null);
  });

  return texture;
}

const iBuffer = new IndexBufferData(new Uint16Array([3, 2, 1, 3, 1, 0]));
vBuffer.create(gl);
iBuffer.create(gl);
const planeShaderData: ShaderData = new ShaderData(ShaderDataGroup.Material);
console.log(ShaderDataGroup, planeShaderData);
// planeShaderData.setTexture("u_Sampler", { _glTexture: create1PixelTexture(gl, [255, 0, 0, 255]) });
planeShaderData.setTexture("u_Sampler", { _glTexture: createTexture(gl, textureUrl), _target: gl.TEXTURE_2D });

engine.update = (gl) => {
  // console.log('--');
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  // 用上面指定的颜色清除缓冲区
  gl.clear(gl.COLOR_BUFFER_BIT);

  planeProgram.bind();
  // gl.bindTexture(gl.TEXTURE_2D, null);
  vBuffer.upload(planeProgram._glProgram, gl);
  iBuffer.upload(gl);
  planeProgram.uploadAll(planeProgram.otherUniformBlock, planeShaderData);
  iBuffer.draw(gl);
  // 面end
};
